#include <iostream>
#include <string>
#include <cstdio>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

void fun()
{
    std::cout<< "hello world" << std::endl;
    _exit(100);
    //exit(100); //退出码为100
    //return 100; //退出码为 main 函数的退出码
}

// int main() // 野指针
// {
//     char *p = nullptr;
//     *p = 'a';
// }


int main()
{
    pid_t id = fork();
    if(id < 0)
    {
        printf("errno: %d, errstring: %s\n", errno, strerror(errno));
        return errno;
    }
    else if(id == 0) //子进程
    {
        int cnt = 5;
        while(cnt)
        {
            printf("子进程运行中, pid: %d\n", getpid());
            cnt--;
            sleep(1);
            //int a = 1/0; //进程异常，子进程会挂掉，但是父进程不会有影响（进程独立性）
        }
        // char *p = nullptr;
        // *p = 'a'; // 此时退出信息为 11
        // 可不可以使用全局变量来获取子进程的退出码呢？ -- 不可以，只能通过系统调用获取
        exit(123);
    }
    else
    {
        sleep(3);
        //pid_t rid = wait(nullptr);
        //pid_t rid = waitpid(-1, nullptr, 0); // 和上面 wait 调用作用是一样的
        int status = 0;
        //pid_t rid = waitpid(id + 1, &status, 0); // 把子进程的退出信息获得 --> 0
        pid_t rid = waitpid(id, &status, 0); 
        
        if(rid > 0) // 子进程等待
        {
            //printf("wait sub process success, rid: %d\n", rid);
            //printf("wait sub process success, rid: %d, status: %d\n", rid, status);
            // 提取当前进程退出码（位图）
            if(WIFEXITED(status))
            {
                printf("wait sub process success, rid: %d, status code: %d\n",rid, WEXITSTATUS(status));
            }
            else
            {
                printf("child process quit error!\n");
            }
            // 位操作
            //printf("wait sub process success, rid: %d, status code: %d, exit signal: %d\n",rid, (status>>8)&0xFF, status&0x7F);
             // 比如 上面子进程exit(123)则输出123
        }
        else
        {
            perror("waitpid");
        }
        while(true)
        {
            printf("我是父进程: pid: %d\n", getpid());
            sleep(1);
        }
    }

    return 0;
}


// int main()
// {
//     printf("进程运行结束!\n");
//     sleep(2);
//     exit(5);
//     sleep(2);
//     return 10;
// }


// int main()
// {
//     fun();
//     std::cout << "进程正常退出" << std::endl;
    
//     //for(int i = 0; i < 200; i++)
//     //{
//     //    std::cout <<"code: "<<i <<", errstring：" <<strerror(i)<<std::endl; 
//     //}

//     // printf("Before： errno: %d, errstring: %s\n", errno, strerror(errno));

//     // FILE* fp = fopen("./log,txt", "r");
//     // if(fp == nullptr)
//     // {   
//     //     printf("After：errno: %d, errstring: %s\n", errno, strerror(errno));
//     //     return errno;
//     // }

//     //std::cout << "hello bit" << std::endl;
//     return 10;
// }